package org.matrix.base
{
	import flash.geom.Matrix;
	
	import mx.core.ClassFactory;

	public final class Operator
	{
		private static var internalMatrix:Matrix2D
		public function get matrix():Matrix2D		{return internalMatrix}
		public function set matrix(matrix:Matrix2D):void
		{
			if (matrix == null)
			{
				internalMatrix = null;
				d1 = null;		d2 = null;		d3 = null;
				d4 = null;		d5 = null;		d6 = null;
				d7 = null;//	d8 = null;		d9 = null;
				//dA = null;		dB = null;		dC = null;
				//dD = null;		dE = null;		dF = null;
				d1Dirty = false;	d2Dirty = false;	d3Dirty = false;
				d4Dirty = false;	d5Dirty = false;	d6Dirty = false;
				d7Dirty = false;//	d8Dirty = false;	d9Dirty = false;
				//dADirty = false;	dBDirty = false;	dCDirty = false;
				//dDDirty = false;	dEDirty = false;	dFDirty = false;
				numberOfItems = 0;
				
				dFLenght = 0;	dELenght = 0;	dDLenght = 0;
				dCLenght = 0;	dBLenght = 0;	dALenght = 0;
				d9Lenght = 0;	d8Lenght = 0;	d7Lenght = 0;
				d6Lenght = 0;	d5Lenght = 0;	d4Lenght = 0;
				d3Lenght = 0;	d2Lenght = 0;
			}
			else
			{
				depth = matrix.depth;
				numberOfItems = matrix.numberOfItems;
				dimensions = matrix.dimensions;
				d2Lenght = matrix.d2Lenght;
				for (var i:uint = 3; i++ < dimensions;)
					this['d'+i+'Lenght'] = this['d'+(i-1)+'Lenght'];
				switch(dimensions)
				{
					case 2:		d2 = 		  matrix.d2;		d2Dirty = true;		break //label2;
					case 3:		d3 = Matrix3D(matrix).d3;		d3Dirty = true;		break //label3;
					case 4:		d4 = Matrix4D(matrix).d4;		d4Dirty = true;		break //label4;
					case 5:		d5 = Matrix5D(matrix).d5;		d5Dirty = true;		break //label5;
					case 6:		d6 = Matrix6D(matrix).d6;		d6Dirty = true;		break //label6;
					case 7:		d7 = Matrix7D(matrix).d7;		d7Dirty = true;		break //label7;
					//case 8:	d8 = Matrix8D(matrix.d2;		d8Dirty = true;		break label8;
					//case 9:	d9 = Matrix9D(matrix.d2;		d9Dirty = true;		break label9;
					//case 10:	dA = Matrix10D(matrix.d2;		dADirty = true;		break labelA;
					//case 11:	dB = Matrix11D(matrix.d2;		dBDirty = true;		break labelB;
					//case 12:	dC = Matrix12D(matrix.d2;		dCDirty = true;		break labelC;
					//case 13:	dD = Matrix13D(matrix.d2;		dDDirty = true;		break labelD;
					//case 14:	dE = Matrix14D(matrix.d2;		dEDirty = true;		break labelE;
					//case 15:	dF = Matrix15D(matrix.d2;		dFDirty = true;		break labelF;
				}
				//labelF:		dFLenght = Matrix15D(matrix).dFLenght;
				//labelE:		dFLenght = Matrix14D(matrix).dELenght;
				//labelD:		dFLenght = Matrix13D(matrix).dDLenght;
				//labelC:		dFLenght = Matrix12D(matrix).dCLenght;
				//labelB:		dFLenght = Matrix11D(matrix).dBLenght;
				//labelA:		dFLenght = Matrix10D(matrix).dALenght;
				//label9:		dFLenght = Matrix9D(matrix).d9Lenght;
				//label8:		dFLenght = Matrix8D(matrix).d8Lenght;
				//label7:		d7Lenght = Matrix7D(matrix).d7Lenght;
				//label6:		d6Lenght = Matrix6D(matrix).d6Lenght;
				//label5:		d5Lenght = Matrix5D(matrix).d5Lenght;
				//label4:		d4Lenght = Matrix4D(matrix).d4Lenght;
				//label3:		d3Lenght = Matrix3D(matrix).d3Lenght;
				//label2:		d2Lenght = matrix.d2Lenght;
			}
		}
		
		public function get clone():IMatrix
		{
			const iMatrix:Class = Class('Matrix'+dimensions+'D')
			const clone:Matrix2D = new iMatrix(depth);
			
			for (var i:uint = dimensions; i -- > 1;)
				internalMatrix['d'+i+'Index'] = 0;
			internalMatrix.d1Index = depth;
			
			for (i = numberOfItems; i -- >= 1;)
				clone.next = internalMatrix.next;
			return clone;
		}
		
		public static function isEqual(m:IMatrix):Boolean
		{
			return internalMatrix.numberOfItems == Matrix2D(m).numberOfItems;
		}
		
		/**
		 * 		add to the internal matrix
		 */
		public static function add(matrix:IMatrix):void
		{
//			for (var i:uint = dimensions; i -- > 1;)
//				internalMatrix['d'+i+'Index'] = 0;
//			internalMatrix.d1Index = depth;
			matrix.index = uint.MAX_VALUE;
			internalMatrix.index = uint.MAX_VALUE;
			for (var i:uint = numberOfItems; i -- >= 1;)
				internalMatrix.next += matrix.next; 
		}
		
		/**
		 *		multiplying the internal matrix
		 */
		public static function multiply(matrix:IMatrix):void
		{
		}
		
//		final protected function d3Dec(recursive:Boolean = false):void 
//		{
//			if (recursive)
//				d2Index = depth -1;
//			else
//				throw new Error('');
//		}
//		final protected function d2Dec(recursive:Boolean = false):void
//		{
//			if (d2Index -- == 0)
//				d3Dec(d2Dirty = true);
//			if (recursive)
//				d1Index = depth - 1;
//		}
//		final protected function dec():void
//		{
//			if (d1Index -- == 0)
//			{
//				d2Dec(d1Dirty = true);
//				validate();
//			}
//			else
//				_current = d1[d1Index];
//			_index --
//			if (++ _index == maxIndex)
//				_index = 0;
//		}
		
		private static var depth:uint;
		private static var numberOfItems:uint;
		private static var dimensions:uint;
		
		private static var d1Index:uint;
		private static var d1Dirty:Boolean;
		private static var d1:Vector.<Number>;
		private static var d2Lenght:uint;
		private static var d2Index:uint;
		private static var d2Dirty:Boolean;
		private static var d2:Vector.<Vector.<Number>>;
		private static var d3Lenght:uint;
		private static var d3Index:uint;
		private static var d3Dirty:Boolean;
		private static var d3:Vector.<Vector.<Vector.<Number>>>;
		private static var d4Lenght:uint;
		private static var d4Index:uint;
		private static var d4Dirty:Boolean;
		private static var d4:Vector.<Vector.<Vector.<Vector.<Number>>>>;
		private static var d5Lenght:uint;
		private static var d5Index:uint;
		private static var d5Dirty:Boolean;
		private static var d5:Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>;
		private static var d6Lenght:uint;
		private static var d6Index:uint;
		private static var d6Dirty:Boolean;
		private static var d6:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>;
		private static var d7Lenght:uint;
		private static var d7Index:uint;
		private static var d7Dirty:Boolean;
		private static var d7:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>;
		private static var d8Lenght:uint;
		private static var d8Index:uint;
		private static var d8Dirty:Boolean;
		private static var d8:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>;
		private static var d9Lenght:uint;
		private static var d9Index:uint;
		private static var d9Dirty:Boolean;
		private static var d9:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>;
		private static var dALenght:uint;
		private static var dAIndex:uint;
		private static var dADirty:Boolean;
		private static var dA:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>>;
		private static var dBLenght:uint;
		private static var dBIndex:uint;
		private static var dBDirty:Boolean;
		private static var dB:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>>>;
		private static var dCLenght:uint;
		private static var dCIndex:uint;
		private static var dCDirty:Boolean;
		private static var dC:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>>>>;
		private static var dDLenght:uint;
		private static var dDIndex:uint;
		private static var dDDirty:Boolean;
		private static var dD:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>>>>>;
		private static var dELenght:uint;
		private static var dEIndex:uint;
		private static var dEDirty:Boolean;
		private static var dE:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>>>>>>;
		private static var dFLenght:uint;
		private static var dFIndex:uint;
		private static var dFDirty:Boolean;
		private static var dF:Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Vector.<Number>>>>>>>>>>>>>>>;
	}
}